<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\LihuaOrder;
use app\common\model\LihuaOrderPayment;
use app\common\model\LihuaPaylog;
use app\common\model\User;
use my\WxPay;
use my\AliPay;
use think\Db;

/**
 * 支付
 */
class Pay extends Api
{

    protected $_error = '';
    protected $noNeedLogin = ['wxpay', 'wxcb', 'alipay', 'alicb', 'code'];
    protected $noNeedRight = ['*'];

    public function _initialize()
    {
        parent::_initialize();
    }

    /**
     * 设置错误信息.
     * @ApiInternal()
     */
    public function setError($error)
    {
        $this->_error = $error;
    }

    /**
     * 获取错误信息.
     * @ApiInternal()
     */
    public function getError()
    {
        return $this->_error;
    }

    /**
     * 获取订单金额等信息
     * @ApiInternal()
     */
    private function getOrderInfo($sn)
    {
        if ($sn) {
            $field = 'id,sn,user_id,city_id,city_name,store_id,store_name,order_amount,platform,pay_type,status';
            $row = LihuaOrder::where('sn', $sn)->field($field)->find();
            if ($row) {
                if ($row['status'] == 1) return $row;
                $this->setError($row['status'] > 1 ? '订单已支付或货到付款' : '订单已取消');
            } else $this->setError('订单不存在');
        } else $this->setError('订单不存在');
        return false;
    }

    /**
     * 获取支付配置
     * @ApiInternal()
     */
    private function getPayConf($city_id = 0, $pay_type = 1, $platform = 'app')
    {
        if (in_array($pay_type, [1, 2])) {
            if (in_array($platform, ['app', 'xcx'])) {
                $table = $pay_type == 1 ? 'lihua_alipay' : 'lihua_wxpay';
                $type  = $platform == 'app' ? 1 : 2;
                $row   = Db::name($table)->where(['city_id' => $city_id, 'type' => $type])
                    ->field('id,city_id,type,name', true)->find();
                if ($row) return $row;
                $this->setError('未配置支付参数');
            } else $this->setError('平台错误');
        } else $this->setError('请选择支付方式');
        return false;
    }

    /**
     * 获取订单信息及支付配置
     * @ApiInternal()
     */
    protected function getOrderInfoAndPayConf($sn = '', $pay_type = 1)
    {
        $info = $this->getOrderInfo($sn);
        if ($info === false) return false;

        $conf = $this->getPayConf($info['city_id'], $pay_type, $info['platform']);
        if ($conf === false) return false;

        return [$info, $conf];
    }

    /**
     * 货到付款
     *
     * @ApiMethod  (POST)
     * @ApiParams  (name="sn", type="string", required=true, description="订单号")
     * @ApiReturn  ({"code":1,"msg":"OK","time":"1550820650","data":{}})
     */
    public function code()
    {
        $sn = $this->request->post('sn');
        $info = $this->getOrderInfo($sn);
        if ($info === false) $this->error($this->getError());

        LihuaOrder::update(['pay_type' => 4, 'status' => 2], ['sn' => $sn]);
        $this->success('OK');
    }

    /**
     * 微信支付
     *
     * @ApiMethod  (POST)
     * @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams  (name="sn", type="string", required=true, description="订单号")
     * @ApiReturn  ({"code":1,"msg":"OK","time":"1550820650","data":{"appid":"","partnerid":"","prepayid":"","package":"","noncestr":"","timestamp":"","sign":""}})
     */
    public function wxpay()
    {
        $sn  = $this->request->post('sn');
        $arr = $this->getOrderInfoAndPayConf($sn, 2);
        if ($arr === false) $this->error($this->getError());
        list($info, $conf) = $arr;

        /*$url = 'https://api.weixin.qq.com/sns/jscode2session';
        $params = [
            'appid'   => $conf['appid'],
            'secret'  => $conf['app_secret'],
            'js_code' => '',
            'grant_type' => 'authorization_code',
        ];*/

        $config = [
            'appid'      => $conf['appid'],//微信开放平台上的应用ID
            'mch_id'     => $conf['mch_id'],//商户号
            'api_key'    => $conf['api_key'],//微信商户平台上自己设定的api密钥32位
            'notify_url' => config('api_url') . '/pay/wxcb.html',//回调地址
            'trade_type' => $info['platform'] == 'xcx' ? 'JSAPI' : 'APP',
        ];
        $wxpay = new WxPay($config);
        $body  = "丽华快餐-{$info['city_name']}-{$info['store_name']}-订单{$sn}";
        $order = $wxpay->unifiedOrder($sn, $info['order_amount'], $body);
        if ($order === false) $this->error($wxpay->err_msg);

        $this->success('OK', $order);
    }

    /**
     * 微信支付回调
     *
     * @ApiInternal()
     */
    public function wxcb()
    {
        $xml   = file_get_contents('php://input');
        $wxpay = new WxPay();
        $res   = $wxpay->xmlstr_to_array($xml);
        if ($res['return_code'] == 'SUCCESS') {
            if ($res['result_code'] == 'SUCCESS') {
                $row = $this->getOrderInfo($res['out_trade_no']);
                if ($row) {
                    $money = $row['order_amount'];
                    if ($money * 100 == $res['total_fee']) {

                        if ($res['time_end']) {
                            $time_end = date_create($res['time_end']);
                            $pay_time = date_format($time_end,"Y-m-d H:i:s");
                        }

                        if ($res['result_code'] == 'SUCCESS') {
                            $pay_ok = 1;
                            $result_des = '交易支付成功';
                        } else {
                            $pay_ok = 0;
                            $result_des = $res['err_code'].'：'.$res['err_code_des'];
                        }

                        if (!isset($pay_time)) $pay_time = date('Y-m-d H:i:s');
                        $data = [
                            'type'           => 2,//微信支付
                            'trade_no'       => $res['transaction_id'],
                            'out_trade_no'   => $res['out_trade_no'],
                            'total_fee'      => $money,
                            'order_id'       => $row['id'],
                            'user_id'        => $row['user_id'],//$res['attach']
                            'pay_ok'         => $pay_ok,
                            'pay_time'       => $pay_time,
                            'result_code'    => $res['result_code'],
                            'result_des'     => $result_des,
                            'callbackdata'   => json_encode($res, JSON_UNESCAPED_UNICODE),
                        ];

                        $paylog = LihuaPaylog::create($data);

                        if ($res['result_code'] == 'SUCCESS' && $row['status'] == 1) {
                            $data = [
                                'pay_type'   => 2,
                                'pay_status' => 1,
                                'pay_time'   => $pay_time,
                                'status'     => 2,
                            ];
                            LihuaOrder::update($data, ['id' => $row['id']]);
                            LihuaPaylog::update(['upstatus' => 1], ['id' => $paylog->id]);
                            LihuaOrderPayment::create([
                                'city_id'    => $row['city_id'],
                                'order_id'   => $row['id'],
                                'order_sn'   => $row['sn'],
                                'user_id'    => $row['user_id'],
                                'pay_name'   => '微信支付',
                                'pay_money'  => $money,
                                'is_voucher' => 0,
                            ]);
                        }
                    }
                }
            }
        }
        return xml(['return_code' => 'SUCCESS', 'return_msg' => 'OK']);
    }

    /**
     * 阿里支付
     *
     * @ApiMethod  (POST)
     * @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams  (name="sn", type="string", required=true, description="订单号")
     * @ApiReturn  ({"code":1,"msg":"OK","time":"1550820650","data":{"result":""}})
     */
    public function alipay()
    {
        $sn  = $this->request->post('sn');
        $arr = $this->getOrderInfoAndPayConf($sn, 1);
        if ($arr === false) $this->error($this->getError());
        list($info, $conf) = $arr;

        $config  = [
            'gatewayUrl'         => 'https://openapi.alipay.com/gateway.do',
            'appId'              => $conf['appid'],//应用ID
            'signType'           => 'RSA2',
            'notifyUrl'          => config('api_url') . '/pay/alicb.html',//回调地址
            'rsaPrivateKey'      => $conf['private_key'],//应用私钥
            'alipayrsaPublicKey' => $conf['public_key'],//支付宝公钥
        ];

        $alipay  = new AliPay($config);
        $subject = "丽华快餐-{$info['city_name']}-{$info['store_name']}-订单{$sn}";
        $data    = $alipay->unifiedOrder($sn, $info['order_amount'], $subject, $info['platform']);
        if ($data !== false) $this->success('OK', $data);
        $this->error($alipay->err_msg);
    }

    /**
     * 阿里支付回调
     *
     * @ApiInternal()
     */
    public function alicb()
    {
        require_once ROOT_PATH . '/extend/my/alipay/AopClient.php';

        $sn  = $_POST['out_trade_no'];
        $arr = $this->getOrderInfoAndPayConf($sn, 1);
        if ($arr === false) exit('error');
        list($info, $conf) = $arr;

        $aop  = new \AopClient;
        $aop->alipayrsaPublicKey = $conf['public_key'];
        $flag = $aop->rsaCheckV1($_POST, null, "RSA2");
        if ($flag) {

            $row = LihuaOrder::where('sn', $sn)
                ->field('id,sn,user_id,city_id,store_id,order_amount,status')->find();
            if ($row) {
                $money = $row['order_amount'];
                if ($money == $_POST['total_amount']) {

                    $status = [
                        'WAIT_BUYER_PAY' =>'等待买家付款',
                        'TRADE_CLOSED'   =>'未付款超时关闭',
                        'TRADE_SUCCESS'  =>'交易支付成功',
                        'TRADE_FINISHED' =>'交易结束',
                    ];

                    $data = [
                        'type'           => 1,//支付宝支付
                        'trade_no'       => $_POST['trade_no'],
                        'out_trade_no'   => $_POST['out_trade_no'],
                        'total_fee'      => $_POST['total_amount'],
                        'order_id'       => $row['id'],
                        'user_id'        => $row['user_id'],
                        'pay_ok'         => in_array($_POST['trade_status'], ['TRADE_SUCCESS', 'TRADE_FINISHED']) ? 1 : 0,
                        'pay_time'       => $_POST['gmt_payment'] ? : date('Y-m-d H:i:s'),
                        'result_code'    => $_POST['trade_status'],
                        'result_des'     => isset($status[$_POST['trade_status']]) ? $status[$_POST['trade_status']] : $_POST['trade_status'],
                        'callbackdata'   => json_encode($_POST, JSON_UNESCAPED_UNICODE),
                    ];

                    $paylog = LihuaPaylog::create($data);

                    if (in_array($_POST['trade_status'], ['TRADE_SUCCESS', 'TRADE_FINISHED']) && $row['status'] == 1) {
                        $data = [
                            'pay_type'   => 1,
                            'pay_status' => 1,
                            'pay_time'   => $_POST['gmt_payment'] ? : date('Y-m-d H:i:s'),
                            'status'     => 2,
                        ];
                        LihuaOrder::update($data, ['id' => $row['id']]);
                        LihuaPaylog::update(['upstatus' => 1], ['id' => $paylog->id]);
                        LihuaOrderPayment::create([
                            'city_id'    => $row['city_id'],
                            'order_id'   => $row['id'],
                            'order_sn'   => $row['sn'],
                            'user_id'    => $row['user_id'],
                            'pay_name'   => '支付宝支付',
                            'pay_money'  => $money,
                            'is_voucher' => 0,
                        ]);
                    }

                }
            }
            exit('success');
        }
        exit('error');
    }
}
